import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter_demo/entities/download_task.dart';
import 'package:get/get.dart';
import 'package:path_provider/path_provider.dart';

class DownloadController extends GetxController {
  final dio = Dio()
    ..options = BaseOptions(
      responseType: ResponseType.stream,
      followRedirects: false,
    );
  final taskMap = <String, DownloadTask>{};

  startDownload(String url, {savePath = String}) async {
    if (taskMap.containsKey(url)) {
      return taskMap[url];
    }
    savePath ??= "/$url";
    var absPath = (await getApplicationSupportDirectory()).path + savePath;
    var downloadStart = 0;
    File f = File(absPath);
    if (await f.exists()) {
      downloadStart = f.lengthSync();
    }
    final task = DownloadTask();
    final cancelToken = CancelToken();
    task.cancelToken = cancelToken;
    task.savePath = absPath;
    taskMap[url] = task;
    try {
      await dio.download(
        url,
        savePath,
        cancelToken: cancelToken,
        options: Options(
          headers: {
            /// 分段下载重点位置
            "range": "bytes=$downloadStart-",
          },
        ),
        onReceiveProgress: (process, total) {
          for (final callback in task.callbacks) {
            callback.processCallback?.call(process, total);
          }
        },
      );
      for (final callback in task.callbacks) {
        callback.successCallback?.call();
      }
    } on Exception catch (e) {
      for (final callback in task.callbacks) {
        callback.errorCallback?.call(e);
      }
    }
    return task;
  }

  stopDownload(String url) {
    final task = taskMap[url];
    task?.cancelToken?.cancel();
  }

  listenDownload(String url, TaskCallback callback) {
    final task = taskMap[url];
    if (task != null) {
      task.callbacks.add(callback);
    }
  }

  stopListenDownload(String url, TaskCallback callback) {
    final task = taskMap[url];
    if (task != null) {
      task.callbacks.remove(callback);
    }
  }
}
